﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

public static class EnumExtensions
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public static string ToDescription(this Enum item)
    {
        string name = item.ToString();
        var desc = item.GetType().GetField(name)?.GetCustomAttribute<DescriptionAttribute>();
        return desc?.Description ?? name;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public static string ToDisplayName(this Enum item)
    {
        string name = item.ToString();
        var desc = item.GetType().GetField(name)?.GetCustomAttribute<DisplayAttribute>();
        return desc?.Name ?? name;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public static string ToSummary(this Enum item)
    {
        string name = item.ToString();
        var filed = item.GetType().GetField(name);
        if (filed == null) return name;
        if (filed.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute desc) return desc.Description;
        else if (filed.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute dis) return dis.Name ?? "";
        return name;
        // return  item.GetType().GetField(name)?.GetXmlDocsSummary();
    }
    public static long ToInt64(this Enum item)
    {
        return Convert.ToInt64(item);
    }

    public static List<OptionDTO> ToList(this Enum value, bool ignoreUnKnown = false)
    {
        var enumType = value.GetType();

        if (!enumType.IsEnum)
            return null;
        Array Values = Enum.GetValues(enumType);

        return Values.Cast<Enum>()
            .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown"))
            .Select(x => new OptionDTO
            {
                Data = x.ToSummary(),
                Label = x.ToDescription(),
                Value = x,// (int)x
            }).ToList();
    }

    /// <summary>
    /// 枚举转字典（需获取描述时使用）
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static IDictionary<int, string> EnumToDictionary<T>() where T : System.Enum
    {
        Type type = typeof(T);

        string[] Names = System.Enum.GetNames(type);

        Array Values = System.Enum.GetValues(type);

        IDictionary<int, string> dic = new Dictionary<int, string>();

        string desc = string.Empty;

        for (int i = 0; i < Values.Length; i++)
        {
            T t = (T)System.Enum.Parse(typeof(T), Values.GetValue(i).ToString());

            MemberInfo[] memInfo = type.GetMember(t.ToString());

            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    desc = ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            //GetEnumDesc(T);

            dic.Add((int)Values.GetValue(i), string.IsNullOrEmpty(desc) ? Names[i].ToString() : desc);
        }

        return dic;
    }


    /// <summary>
    ///  返回说明
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static List<OptionDTO> EnumToList<T>() where T : System.Enum
    {
        Type type = typeof(T);

        string[] Names = System.Enum.GetNames(type);

        Array Values = System.Enum.GetValues(type);

        List<OptionDTO> dic = new List<OptionDTO>();

        string desc = string.Empty;

        for (int i = 0; i < Values.Length; i++)
        {
            T t = (T)System.Enum.Parse(typeof(T), Values.GetValue(i).ToString());

            MemberInfo[] memInfo = type.GetMember(t.ToString());

            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    desc = ((DisplayAttribute)attrs[0]).Name;
                }
                else
                {
                    var dattrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (dattrs != null && dattrs.Length > 0)
                    {
                        desc = ((DescriptionAttribute)dattrs[0]).Description;
                    }
                }
            }
            //GetEnumDesc(T);
            dic.Add(new OptionDTO
            {
                Value = (int)Values.GetValue(i),
                Label = string.IsNullOrEmpty(desc) ? Names[i].ToString() : desc,
                Data = Names[i].ToString(),
                Disabled = false,
            });
        }

        return dic;
    }
    /// <summary>
    /// 枚举转字典(无需获取描述时使用)
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static IDictionary<int, string> EnumToDictionary(Type type)
    {
        string[] Names = System.Enum.GetNames(type);

        Array Values = System.Enum.GetValues(type);

        IDictionary<int, string> dic = new Dictionary<int, string>();

        for (int i = 0; i < Values.Length; i++)
        {
            dic.Add((int)Values.GetValue(i), Names[i].ToString());
        }

        return dic;
    }
    public static List<OptionDTO> ToList<T>(bool ignoreUnKnown = false) where T : System.Enum
    {
        var enumType = typeof(T);

        if (!enumType.IsEnum)
            return null;

        return Enum.GetValues(enumType).Cast<Enum>()
             .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown"))
             .Select(x => new OptionDTO
             {
                 Data = x.ToDescription(),
                 Label = x.ToDisplayName(),
                 Value = x
             }).ToList();
    }
}


/// <summary>
/// 下拉操作
/// </summary>
public class OptionDTO
{
    /// <summary>
    /// 
    /// </summary>
    public object? Value { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public string Label { get; set; } = "";
    /// <summary>
    /// 
    /// </summary>
    public string Data { get; set; } = "";
    /// <summary>
    /// 
    /// </summary>
    public bool Disabled { get; set; }
}
